﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RoutingTable
{
    public class NODE
    {
        // DEFINE const ***************************************************************************
        public  const   int TNODE       = 200;   // 전체 노드 수
        public  const   int KCNT        = 5;    // 한 노드가 소유할 키 수
        public  const   int MINUS_X     = 100;
        public  const   int MINUS_Y     = 110;
        public  const   int RANGE       = 60;	// 노드가 수신할 수 있는 범위
		public  const   int EVENT       = 70;	// 노드가 감지할 수 있는 범위
        public  const   int SEED        = 1;
        public  const   int CHLD        = 10;
		public	const	int	LMTHC		= 1;	// Path 변경이 있을 때, 검색할 HC 수
		public	const	int	MAXHC		= 25;
		
		public	const	float	PSM_W	= 0.5f;
		
      
        // Nodes Information    *******************************************************************
        public  int     nodeID;			    // 노드 식별자
        public  float   nodeX;				// 노드 X좌표
        public  float   nodeY;				// 노드 Y좌표    
        public  int     parentID = -1;   	// 부모 식별자
        public  float   distance;           // BS로부터 노드간 거리
        public  int     hc;                 // Hop Count
        public  float   energy;             // 에너지 소모량
		public	int		vc;
        public  int[]   child;              // 자식 노드        
		public	float	psm;
		public	float	pdm;

        public  int     partID;
        public  int[]   keyPool;
        public  int[]   tmpKeyPool;

        Random randomObject = new Random( SEED );

        // NODE Class 초기화   ********************************************************************
        public NODE()
        {
            nodeID      = -1;
            nodeX       = -1;
            nodeY       = -1;
            parentID    = -1;
            distance    = -1.0f;
            hc          = 0;
            energy      = 0.0f;
			vc			= 0;
            child       = new int[CHLD];

            keyPool     = new int[KCNT];
            tmpKeyPool  = new int[KCNT];

			psm			= 0.0f;
			pdm			= 0.0f;
        }


        // 키분배작업    ***************************************************************************
        public void DistributeKeys( NODE nd )
        {
            int tmp = -1;

			nd.partID = randomObject.Next( 0, 9 );

			for ( int i = 0; i < KCNT; i++ )
            {
				tmp = PutRandomKeys( nd.partID );
                nd.keyPool[i] = ChkOverlapKeys( nd, tmp );
                nd.tmpKeyPool[i] = nd.keyPool[i];
            }
        } // public void DistributeKeys()


        // 파티션에서 임의의 키 분배   **************************************************************
        public int PutRandomKeys( int id )
        {
			int	tmp = -1;
			tmp = ( id * 10 ) + randomObject.Next() % 10;
			
            return tmp;
        } // public int PutRandomKeys()


        // 중복키 처리   ***************************************************************************
        public int ChkOverlapKeys( NODE nd, int tmp )
        {
			for ( int i = 0; i < KCNT; i++ )
            {
                if ( nd.tmpKeyPool[i] == tmp )
                {
                    tmp = PutRandomKeys( nd.partID );
                    ChkOverlapKeys( nd, tmp );
                }
            }

            return tmp;
        } // public int ChkOverlapKeys( int tmp )


        // 노드 사이 거리 측정  ********************************************************************
        public float MeasureDistance( float x1, float y1, float x2, float y2 )
        {
			return ( float )Math.Sqrt( ( ( x1 - x2 ) * ( x1 - x2 ) ) + ( ( y1 - y2 ) * ( y1 - y2 ) ) );
        } // public float MeasureDistance


        // 해당 노드 키들 모두 출력   **************************************************************  
        public string PrtKeysofNode( NODE nd )
        {
            string str = "";

			for ( int k = 0; k < NODE.KCNT; k++ )
				str = str + nd.keyPool[k] + " ";
            
			return str;
        } // public string PrtKeysofNode( int nd )


		// Choose a Node Randomly after Occuring a Event	***************************************
		public int ChooseNode()
		{
			Random r = new Random( ( int )DateTime.Now.Ticks );
			System.Threading.Thread.Sleep( 1 );
			return r.Next( 1, NODE.TNODE - 1 );
		} // public int ChooseNode()


		// Calcuate Evaluate Result	***************************************************************
		public double EvaluateResult( int trc, int rrc, int shc )
		{
			return ( ( trc / rrc ) * 100 ) + shc;
		} // public double EvaluateResult( float E, int HC, int VC )
    }
}
